package org.example.web;

import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.example.ServerResponse;
import org.example.entity.Order;
import org.example.entity.SysUser;
import org.example.service.IOrderService;
import org.example.service.IUserService;
import org.example.web.form.OrderQueryForm;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;

/**
 * spring mvc与servlet的区别
 * 区别1：参数默认值问题
 *      spring mvc: @RequestParam
 *      servlet：   必须通过编码实现默认值
 * 区别2：前段请求参数，自定绑定到方法参数
 *      serlvet:    request.getParameter("page");
 *      spring mvc: 默认方法参数名与请求参数名一致,如果不一致则不能绑定值，
 *                  不一致时，但是可以通过@RequestParam(value="url请求参数名")
 * 区别3：前段的表单参数，可以直接通过控制器的方法的表单对应的实体类自动接收
 *      serlvet:    request.getParameter("表单元素name"); ,将所有值封装成对象
 *      spring mvc: 前提：表单元素name属性值必须和实体类的属性名一致
 * 区别4：如何返回json数据
 *      servlet：1)fastjson json框架依赖   2）JSON.parseTOString()  将实体或集合转为json对象或数组字符串
 *      spring mvc: 1）默认jackson框架，无需导入json框架
 *                  2）@ResponseBody 指定的控制器方法的返回值转为json字符串 需要导入3个依赖
 * 区别5：前段传递参数为ids=1&ids=2,后端如何接收
 *      servlet:  String[] idsStr = request.getParameterValues("ids")
 *      spring mvc : 控制器的方法通过Integer[] ids;前段参数自动绑定ids数组中，前提：请求参数名与参数名相同
 */
@Controller
@Slf4j
@RequestMapping("/order")
public class OrderController {
    @Resource
    private IOrderService orderService;
    @Resource
    private IUserService userService;
    /**
     * 分页查询订单信息列表
     * @param page  页数
     * @param limit 每页条数
     * @return
     */
    @RequestMapping("/list")
    public String list(OrderQueryForm orderQueryForm,Model model ,
                       @RequestParam(value = "psize",defaultValue = "1") int page,
                       @RequestParam(defaultValue = "3")int limit){
        log.info("参数page:{},参数limit:{},条件参数：{}",page,limit,orderQueryForm);
        //1.参数校验-----默认值

        //2.调用service
        PageInfo<Order> orderPageInfo = orderService.selectByPage(orderQueryForm,page, limit);
        log.info("orderPageInfo:{}",orderPageInfo);
        //3.返回model(数据)和view(网页) request.setAttribute(key,value)
        model.addAttribute("orderPageInfo",orderPageInfo);//key-value

        if(checkOrderQueryForm(orderQueryForm)) {
            return "order/data";
        }

        return "order/list";//WEB-INF/order/list.jsp
    }

    /**
     * 校验订单查询的表单
     * @param orderQueryForm 订单查询表单
     * @return  true:表单有值，false:反之
     */
    private Boolean checkOrderQueryForm(OrderQueryForm orderQueryForm){
        if(orderQueryForm.getUserId()==null&&orderQueryForm.getCreatetime()==null){
            return false;
        }
        return true;
    }

    /**
     * 订单详情
     * @param model 数据模型
     * @param orderId   订单id
     * @return
     */
    @RequestMapping("/info")
    public String info(Model model, Integer orderId) {
        log.info("orderId:{}", orderId);
        //1.参数校验-----默认值
        if (orderId == null) {
//            return "order/list";//跳转到WEB-INF/list.jsp
            return "redirect:list";//重定向到http://localhost:8080/项目名/order/list
        }
        //2.调用service
        Order orderDetail = orderService.info(orderId);
        log.info("查询出来的订单信息为：{}", orderDetail);
        //3.返回model(数据)和view(网页) request.setAttribute(key,value)
        model.addAttribute("orderDetail", orderDetail);

        return "order/info";//WEB-INF/order/list.jsp
    }

    /**
     *  根据id进行更新【异步方式】
     * @param model 数据模型
     * @param order 待更新的订单数据
     * @return
     */
    @RequestMapping("/edit_ayc")
    @ResponseBody //如果不加该注解，则会将方法返回值当成view名称，加上后将返回值转为json返回
//    public String editAyc(Model model,Order order){
    public ServerResponse editAyc(Model model, Order order){
        log.info("参数order:{}",order);
        //1.参数校验-----默认值
        if(order==null){
//            return "{\"id\":-1,\"msg\":\"invalid param error\"}";
            return ServerResponse.invalidParam();
        }
        //2.调用service
        int rows= orderService.updateById(order);
        log.info("更新受影响的行数为：{}",rows);
        //3.返回json对象  {"id":0,"msg":"success"}
//        return "{\"id\":0,\"msg\":\"success\"}";
        return ServerResponse.successWithMsg();
    }

    /**
     *  根据id进行更新【同步方式】
     * @param model 数据模型
     * @param order 待更新的订单数据
     * @return
     */
    @RequestMapping("/edit")
    public String edit(Model model,Order order){
        log.info("参数order:{}",order);
        //1.参数校验-----默认值
        if(order==null){
//            return "order/list";//跳转到WEB-INF/list.jsp
            return "redirect:list";//重定向到http://localhost:8080/项目名/order/list
        }
        //2.调用service
        int rows= orderService.updateById(order);
        log.info("更新受影响的行数为：{}",rows);
        //3.返回model(数据)和view(网页) request.setAttribute(key,value)

        return "redirect:list";//OrderController#list
    }

    /**
     * 删除订单
     * @param model 数据模型
     * @param orderId 订单id
     * @return
     */
    @RequestMapping("/delete")
    public String delete(Model model,Integer orderId){
        log.info("参数orderId:{}",orderId);
        //1.参数校验-----默认值
        if(orderId==null){
            return "redirect:list";//重定向到http://localhost:8080/项目名/order/list
        }
        //2.调用service
        int rows= orderService.deleteById(orderId);
        log.info("更新受影响的行数为：{}",rows);
        //3.返回model(数据)和view(网页) request.setAttribute(key,value)
        return "redirect:list";//OrderController#list
    }
    /**
     * 根据多个id批量删除
     * @param ids id数组
     * @return
     */
    @RequestMapping("/delete_batch")
    public String deleteBatch(Integer[] ids){
        log.info("参数ids=======>"+ Arrays.toString(ids));
        //1.参数校验-----默认值
        if(ids.length<=0){
            return "redirect:list";
        }
        //2.调用service
        int rows = orderService.deleteBatch(ids);
        log.info("删除受影响的行数为：{}",rows);
        //3.返回model(数据)和view(网页) request.setAttribute(key,value)
        return "redirect:list";
    }

    /**
     * 跳转到添加页面
     * @return
     */
    @RequestMapping("to_add")
    public String toAdd(Model model){
        //查询所有未冻结的用户
        //1.校验

        //2.调用service
        List<SysUser> userInfoList = userService.selectAllValid();


        //3.绑定数据返回View
        model.addAttribute("userInfoList",userInfoList);
        return "order/add";
    }

    /**
     * 添加订单
     * @param order 待添加的订单
     * @return
     */
    @RequestMapping("/save")
    @ResponseBody
    public ServerResponse save(Order order){
        log.info("添加订单，参数order========>{}",order);
        //1.校验参数
        if(!checkParam(order)){
            return ServerResponse.invalidParam();
        }
        // 2.调用service
        int rows = orderService.save(order);
        if(rows<=0){
            return ServerResponse.failedWithMsg("添加失败");
        }
        // 3.返回model和View
        return ServerResponse.successWithMsg();
    }

    /**
     * 校验order参数
     * @param order
     * @return
     */
    private boolean checkParam(Order order){
        if(order.getUserId()==null){
            return false;
        }
        //...........
        return true;
    }

    /**
     * 【废弃】已经与上面的list方法合并成一个方法
     * @param orderQueryForm
     * @param model
     * @param page
     * @param limit
     * @return
     */
    @RequestMapping("/search")
//    @ResponseBody
    public String search(OrderQueryForm orderQueryForm,Model model ,
                                 @RequestParam(value = "psize",defaultValue = "1") int page,
                                 @RequestParam(defaultValue = "3")int limit){
        log.info("接收查询请求.......,参数为：{}",orderQueryForm);
        //1.参数校验
        if(!checkParameter(orderQueryForm)){
//            return ServerResponse.invalidParam();
            throw new RuntimeException("参数错误");

        }
        //2.调用service
        PageInfo<Order> orderPageInfo = orderService.search(orderQueryForm,page,limit);
        log.info("orderPageInfo=========>{}",orderPageInfo);
        //3.返回数据改为返回数据和视图  data.jsp  model
//        return ServerResponse.success(orderPageInfo);
        model.addAttribute("orderPageInfo",orderPageInfo);//key-value
        model.addAttribute("orderQueryForm",orderQueryForm);
        return "order/data";

    }

    private Boolean checkParameter(OrderQueryForm orderQueryForm) {
        if(orderQueryForm.getUserId()==null&&orderQueryForm.getCreatetime()==null){
            return false;
        }
        return true;
    }

    @RequestMapping("/export")
    public void export(@RequestParam(value = "psize",defaultValue = "1") int page,
                       HttpServletResponse response){
        //1.参数校验

        //2.调用service
        orderService.export(page,response);
        //3.返回文件流
    }
    @RequestMapping("/export-hu")
    public void exportHu(@RequestParam(value = "psize",defaultValue = "1") int page,
                       HttpServletResponse response){
        //1.参数校验

        //2.调用service
        orderService.exportHutool(page,response);
        //3.返回文件流
    }

    @RequestMapping("/export-easy")
    public void exportEasy(@RequestParam(value = "psize",defaultValue = "1") int page,
                       HttpServletResponse response){
        //1.参数校验

        //2.调用service
        orderService.exportEasyExecl(page,response);
        //3.返回文件流
    }
    /**
     * 报表导入
     * @param multipartFile 包含上传文件所有信息的对象
     */

    @RequestMapping("/import")
    @ResponseBody
    public String importExcel(MultipartFile multipartFile){
        //1.参数校验

        //2.调用service
        return orderService.importEasyExecl(multipartFile);
        //3.返回文件流
    }

}
